#include "TcpClient.hpp"
#include "Agreement.hpp"
#include "HandleMessage.hpp"
#include "Reckoner.hpp"

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        std::cout << "Usage:./client_tcp server_ip server_port" << std::endl;
        return 1;
    }
    std::string server_ip = argv[1]; // "192.168.1.1"
    int server_port = std::stoi(argv[2]);
    int sockfd = ::socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        std::cout << "create socket failed" << std::endl;
        return 2;
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(server_port);
    server_addr.sin_addr.s_addr = inet_addr(server_ip.c_str());

    // client 不需要显示的进行bind, tcp是面向连接的, connect 底层会自动进行bind
    int n = ::connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (n < 0)
    {
        std::cout << "connect failed" << std::endl;
        return 3;
    }
    // echo client

    std::string s;
    while (true)
    {
        //从标准输入中读取
        int x, y;
        char oper;
        std::cout << "input x: ";
        while (!(std::cin >> x)) // 检查输入是否成功
        {
            std::cerr << "Invalid input for x. Please enter an integer.\n";
            std::cin.clear();                                                   // 清除输入流的错误状态
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 清空缓冲区
            std::cout << "输入错误，重新输入： ";
            continue;
        }

        std::cout << "input y: ";
        while (!(std::cin >> y)) // 检查输入是否成功
        {
            std::cerr << "Invalid input for y. Please enter an integer.\n";
            std::cin.clear();                                                   // 清除输入流的错误状态
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 清空缓冲区
            std::cout << "输入错误，重新输入： ";
            continue;
        }

        std::cout << "input oper: ";
        while (!(std::cin >> oper) || !(oper == '+' || oper == '-' || oper == '*' || oper == '/')) // 检查输入是否成功
        {
            std::cerr << "Invalid input for operator. Please enter +, -, * or /.\n";
            std::cin.clear();                                                   // 清除输入流的错误状态
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 清空缓冲区
            std::cout << "输入错误，重新输入： ";
            continue;
        }

        Request req(x, y, oper);
        // 进行序列化
        std::string message;
        req.Serialize(&message);

        // 添加报头
        AddHeader(&message);

        // 进行写入
        n = ::write(sockfd, message.c_str(), message.size());
        if (n > 0)
        {
            char inbuffer[1024];
            int m = ::read(sockfd, inbuffer, sizeof(inbuffer));
            if (m > 0)
            {
                inbuffer[m] = 0;
                // 完整报文
                s += inbuffer;
                std::string out;
                while (SplitMessage(s, &out))
                {
                    // 进行反序列化
                    Response res;
                    res.Deserialization(out);
                    std::cout << res.GetRes() << std::endl;
                }
            }
            else
                break;
        }
        else
            break;
    }

    ::close(sockfd);
    return 0;
}